#!/usr/bin/python
#-*-coding:utf-8-*-
 
###############################################################
## Name       : gen_rtl_dummy
## Author     : xiaotu
## Time       : 2023-03-10 11:11:19
## Description:
## 
## 
###############################################################
 
import sys
import os
import re
import argparse

class Port:
  def __init__(self, name, type="wire", port="input", width = ""):
    self.name   = name
    self.type   = type
    self.port   = port
    self.width  = width
    self.real_width = ""

  def __str__(self):
    str = "Class Port\n"
    str = str + "    name   : %s\n" % self.name
    str = str + "    type   : %s\n" % self.type
    str = str + "    port   : %s\n" % self.port
    str = str + "    width  : %s\n" % self.width
    return str

  def sys_real_width(self):
    if self.width == "":
      self.real_width = "1"
      return
    else:
      self.real_width = re.search(r"\[(.*)\]", self.width).group(1)

    re_case0 = re.search(r"(.*)(\+|\-)\s*:(.*)", self.real_width)
    re_case1 = re.search(r"(.*):(.*)", self.real_width)
    if re_case0:
      self.real_width = re_case0.group(3).strip()
    elif re_case1:
      self.real_width = "({0})-({1})+1".format(re_case1.group(1).strip(), re_case1.group(2).strip())
    else:
      self.real_width = "1"

  def gen_declare(self):
    str = "  {0} {1} {2},".format(self.port, self.width, self.name)
    return str

  def gen_tie0(self):
    self.sys_real_width()
    tie0 = "{(" + self.real_width + ")" + "{1'b0}}"
    str = "assign {0} = {1};".format(self.name, tie0)
    return str
    
pass

def input_args_proc():
  parser = argparse.ArgumentParser(description="argparse info")
  parser.add_argument('-o', action='store_true', default=False, help='open this script')
  parser.add_argument('file', default="input.v", help='input rtl.v')
  result = parser.parse_args()
  if result.o == True:
      os.system("gvim %s" % __file__)
      sys.exit(0)
  rtl_file = result.file
  (module_name, extension) = os.path.splitext(rtl_file)
  #print(module_name, rtl_file)
  return module_name, rtl_file, extension

def del_note_code(handle):
  ret_handle = []
  del_flag = 0
  for line in handle:
    re_s  = re.search(r"^\/\*", line)
    re_e  = re.search(r"\*\/", line)
    re_se = re.search(r"^\/\*.*\*\/$", line)
    line  = re.sub(r"\/\/.*$", "", line)
    if re_se: # /*xxxxx*/
      continue
    elif re_s:# /*
      del_flag = 1
    elif re_e:# */
      del_flag = 0
      continue

    if del_flag != 1:
      ret_handle.append(line)
  return ret_handle

def width_space_ex(matched):
  return " " + matched.group(1) + " "

def sys_rtl_file(file):
  signal_list = []
  param_list = []
  with open (file, "r") as rtl:
    handle = rtl.readlines()
    handle = del_note_code(handle)
    for line in handle:
      name = ""
      type = "wire"
      port = "input"
      width = ""
      line = line.strip()
      line = re.sub("(\[.*\])", width_space_ex, line)
      re_port = re.search(r"^\s*(input|output)(\s+wire|\s+reg)?\s+(\[.*\])?\s*([\s,\w]+)\s*", line)
      if re_port:
        port = re_port.group(1).strip()
        if re_port.group(2):
          type = re_port.group(2).strip()
        if re_port.group(3):
          width = re_port.group(3)
        for sig in re_port.group(4).split(r"\s*,\s*"):
          name = sig.strip(",")
          name = name.strip()
          s = Port(name, type, port, width)
          signal_list.append(s)

      re_param = re.search(r"^\s*parameter\s+", line)
      if re_param:
        line = re.sub(r";", ",", line)
        param_list.append(line)

  return signal_list, param_list

def gen_title(module_name):
  title_list = []
  user = os.popen('whoami').readline()
  date = os.popen('date "+%Y-%m-%d %H:%M:%S"').readline()
  name = module_name + "_dummy"

  title_list.append("//#############################################################")
  title_list.append("// Name       :" + name.strip())
  title_list.append("// Author     :" + user.strip())
  title_list.append("// Time       :" + date.strip())
  title_list.append("// Description:")
  title_list.append("// ")
  title_list.append("// ")
  title_list.append("//#############################################################")
  title_list.append("")
  return title_list

def gen_dummy(module_name, signal_list, param_list):
  dummy_list = gen_title(module_name)
  if len(param_list) > 0:
    dummy_list.append("module {0} #(".format(module_name))
    dummy_list.extend(param_list)
    dummy_list.append(")(")
  else:
    dummy_list.append("module {0} (".format(module_name))

  for sig in signal_list:
    dummy_list.append(sig.gen_declare())

  dummy_list[-1] = re.sub(r",$", "", dummy_list[-1])
  dummy_list.append(");")
  dummy_list.append("")
  dummy_list.append("endmodule")
  
  return dummy_list

def gen_dummy_with_tie0(module_name, signal_list, param_list):
  dummy_list = gen_title(module_name)
  if len(param_list) > 0:
    dummy_list.append("module {0} #(".format(module_name))
    dummy_list.extend(param_list)
    dummy_list.append(")(")
  else:
    dummy_list.append("module {0} (".format(module_name))

  for sig in signal_list:
    dummy_list.append(sig.gen_declare())

  dummy_list[-1] = re.sub(r",$", "", dummy_list[-1])
  dummy_list.append(");")
  dummy_list.append("")
  
  for sig in signal_list:
    if sig.port == "output":
      dummy_list.append(sig.gen_tie0())

  dummy_list.append("")
  dummy_list.append("endmodule")
  
  return dummy_list

def write_list(list, file = ""):
  if file == "":
    for line in list:
      print(line + "\n")
  else:
    with open(file, "w") as handle:
      for line in list:
        handle.write(line + "\n")

def main():
  print("%s is working" % __file__)
  module_name, rtl_file, extension = input_args_proc()
  signal_list, param_list = sys_rtl_file(rtl_file)
  sel = input('''1.生成dummy文件
2.生成dummy文件，输出信号tie0
选择你要进行的操作：''')
  
  if sel == 1:
      dummy_list = gen_dummy(module_name, signal_list, param_list)
      write_list(dummy_list, "./{0}_dummy{1}".format(module_name, extension))
      os.system("gvim " + "./{0}_dummy{1}".format(module_name, extension))
  if sel == 2:
      dummy_list = gen_dummy_with_tie0(module_name, signal_list, param_list) 
      write_list(dummy_list, "./{0}_dummy_tie0{1}".format(module_name, extension))
      os.system("gvim " + "./{0}_dummy_tie0{1}".format(module_name, extension))
 
if __name__ == "__main__":
    main()
